package de.karlNet.sambamanager.ldapController.commands;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.stereotype.Controller;

import de.karlNet.sambamanager.ldapModel.LdapGroup;
import de.karlNet.sambamanager.ldapModel.LdapObject;
import de.karlNet.sambamanager.ldapModel.dto.LdapUserCreationDTO;

@Controller
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AddUserToGroup extends BaseCommand {

	private HashMap<String, List<LdapObject>> subMembers;
	private static final String MEMBER_ATTR_NAME = "member";

	public List<LdapGroup> optimizeMembership(List<LdapGroup> ldapGroups) {
		this.subMembers = new HashMap<String, List<LdapObject>>();
		List<LdapGroup> optimizedMembership = new ArrayList<LdapGroup>(
				ldapGroups);
		List<LdapGroup> alreadyVisited = new ArrayList<LdapGroup>();
		for (LdapObject ldapNestable : ldapGroups) {
			this.subMembers.put(ldapNestable.getDn().toLowerCase(),
					this.ldapMemberTree.getAllChildrenOfDN(ldapNestable));
		}
		for (LdapGroup memberShip : ldapGroups) {
			if (alreadyVisited.contains(memberShip)) {
				continue;
			}
			for (LdapGroup memberShipToCheck : optimizedMembership) {
				if (this.subMembers.get(memberShip.getDn().toLowerCase())
						.contains(memberShipToCheck)) {
					optimizedMembership.remove(memberShipToCheck);
					alreadyVisited.add(memberShipToCheck);
					break;
				}
			}
		}
		return optimizedMembership;
	}

	public void addUserToGroupItself(LdapUserCreationDTO creationDTO) {
		for (LdapGroup ldapGroup : this.optimizeMembership(creationDTO
				.getMemberShips())) {

			DirContextOperations groupContextOperations = ldapTemplate
					.lookupContext(ldapGroup.getDn());
			String[] currentMembers = groupContextOperations
					.getStringAttributes(MEMBER_ATTR_NAME);
			List<String> dnUserFullList = new ArrayList<String>();
			if (currentMembers != null && currentMembers.length > 0) {
				dnUserFullList.addAll(Arrays.asList(currentMembers));
			}
			dnUserFullList.add(creationDTO.getLdapUser().getDn());
			groupContextOperations.setAttributeValues(MEMBER_ATTR_NAME,
					dnUserFullList.toArray(new String[dnUserFullList.size()]));
			this.ldapTemplate.modifyAttributes(groupContextOperations);

		}
		this.resetTrees();
	}
}
